import { ApiResponse } from '@/types';

// API客户端配置
interface ApiClientConfig {
  baseURL: string;
  timeout: number;
  headers: Record<string, string>;
}

// 默认配置
const defaultConfig: ApiClientConfig = {
  baseURL: '/api',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
};

// 请求拦截器类型
type RequestInterceptor = (config: RequestInit) => RequestInit | Promise<RequestInit>;

// 响应拦截器类型
type ResponseInterceptor = (response: Response) => Response | Promise<Response>;

// API客户端类
class ApiClient {
  private config: ApiClientConfig;
  private requestInterceptors: RequestInterceptor[] = [];
  private responseInterceptors: ResponseInterceptor[] = [];

  constructor(config: Partial<ApiClientConfig> = {}) {
    this.config = { ...defaultConfig, ...config };
    this.setupDefaultInterceptors();
  }

  // 设置默认拦截器
  private setupDefaultInterceptors() {
    // 请求拦截器：添加认证token
    this.addRequestInterceptor((config) => {
      const token = localStorage.getItem('auth_token');
      if (token) {
        config.headers = {
          ...config.headers,
          Authorization: `Bearer ${token}`,
        };
      }
      return config;
    });

    // 响应拦截器：处理通用错误
    this.addResponseInterceptor(async (response) => {
      if (response.status === 401) {
        // 清除token并跳转到登录页
        localStorage.removeItem('auth_token');
        window.location.href = '/login';
        throw new Error('用户未认证');
      }
      
      if (response.status >= 500) {
        throw new Error('服务器内部错误');
      }
      
      return response;
    });
  }

  // 添加请求拦截器
  addRequestInterceptor(interceptor: RequestInterceptor) {
    this.requestInterceptors.push(interceptor);
  }

  // 添加响应拦截器
  addResponseInterceptor(interceptor: ResponseInterceptor) {
    this.responseInterceptors.push(interceptor);
  }

  // 执行请求拦截器
  private async executeRequestInterceptors(config: RequestInit): Promise<RequestInit> {
    let finalConfig = config;
    for (const interceptor of this.requestInterceptors) {
      finalConfig = await interceptor(finalConfig);
    }
    return finalConfig;
  }

  // 执行响应拦截器
  private async executeResponseInterceptors(response: Response): Promise<Response> {
    let finalResponse = response;
    for (const interceptor of this.responseInterceptors) {
      finalResponse = await interceptor(finalResponse);
    }
    return finalResponse;
  }

  // 基础请求方法
  private async request<T = any>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<T> {
    const url = `${this.config.baseURL}${endpoint}`;
    
    // 合并配置
    let config: RequestInit = {
      ...options,
      headers: {
        ...this.config.headers,
        ...options.headers,
      },
    };

    // 执行请求拦截器
    config = await this.executeRequestInterceptors(config);

    // 添加超时控制
    const controller = new AbortController();
    const timeoutId = setTimeout(() => {
      controller.abort();
    }, this.config.timeout);

    config.signal = controller.signal;

    try {
      const response = await fetch(url, config);
      clearTimeout(timeoutId);

      // 执行响应拦截器
      const finalResponse = await this.executeResponseInterceptors(response);

      // 检查响应状态
      if (!finalResponse.ok) {
        const errorData = await finalResponse.text();
        let errorMessage = `HTTP ${finalResponse.status}: ${finalResponse.statusText}`;
        
        try {
          const parsedError = JSON.parse(errorData);
          errorMessage = parsedError.message || errorMessage;
        } catch {
          // 解析失败时使用默认错误消息
        }
        
        throw new Error(errorMessage);
      }

      // 解析响应数据
      const contentType = finalResponse.headers.get('content-type');
      if (contentType && contentType.includes('application/json')) {
        return await finalResponse.json();
      } else {
        return await finalResponse.text() as T;
      }
    } catch (error) {
      clearTimeout(timeoutId);
      
      if (error instanceof Error && error.name === 'AbortError') {
        throw new Error('请求超时');
      }
      
      throw error;
    }
  }

  // GET请求
  async get<T = any>(endpoint: string, params?: Record<string, any>): Promise<T> {
    let url = endpoint;
    
    if (params) {
      const searchParams = new URLSearchParams();
      Object.entries(params).forEach(([key, value]) => {
        if (value !== undefined && value !== null) {
          searchParams.append(key, String(value));
        }
      });
      
      if (searchParams.toString()) {
        url += `?${searchParams.toString()}`;
      }
    }

    return this.request<T>(url, { method: 'GET' });
  }

  // POST请求
  async post<T = any>(endpoint: string, data?: any): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'POST',
      body: data ? JSON.stringify(data) : undefined,
    });
  }

  // PUT请求
  async put<T = any>(endpoint: string, data?: any): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'PUT',
      body: data ? JSON.stringify(data) : undefined,
    });
  }

  // PATCH请求
  async patch<T = any>(endpoint: string, data?: any): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'PATCH',
      body: data ? JSON.stringify(data) : undefined,
    });
  }

  // DELETE请求
  async delete<T = any>(endpoint: string): Promise<T> {
    return this.request<T>(endpoint, { method: 'DELETE' });
  }

  // 上传文件
  async upload<T = any>(endpoint: string, file: File, data?: Record<string, any>): Promise<T> {
    const formData = new FormData();
    formData.append('file', file);
    
    if (data) {
      Object.entries(data).forEach(([key, value]) => {
        formData.append(key, String(value));
      });
    }

    return this.request<T>(endpoint, {
      method: 'POST',
      body: formData,
      headers: {
        // 不设置Content-Type，让浏览器自动设置multipart/form-data边界
      },
    });
  }

  // 下载文件
  async download(endpoint: string, filename?: string): Promise<void> {
    const response = await this.request<Blob>(endpoint, {
      method: 'GET',
    });

    // 创建下载链接
    const blob = new Blob([response]);
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename || 'download';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
  }

  // 设置基础URL
  setBaseURL(baseURL: string) {
    this.config.baseURL = baseURL;
  }

  // 设置默认headers
  setDefaultHeaders(headers: Record<string, string>) {
    this.config.headers = { ...this.config.headers, ...headers };
  }

  // 设置超时时间
  setTimeout(timeout: number) {
    this.config.timeout = timeout;
  }
}

// 创建默认API客户端实例
export const apiClient = new ApiClient();

// 导出ApiClient类供其他地方使用
export { ApiClient };
export default apiClient;